import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { FormBuilder, FormGroup, } from '@angular/forms';
import { RestService } from '../../services/rest.service';
import { Observable } from 'rxjs/Observable';

import * as _ from 'lodash';

@Component({
  selector: 'app-bselection',
  templateUrl: './bselection.component.html'
})
export class BselectionComponent implements OnInit {
  @Output() change = new EventEmitter<any>();
  @Input() readonly;
  @Input() bedId;
  @Input() unique;

  formGroup: FormGroup;
  institution: any;
  bedData: any = {};
  bed: any;

  buildings = [];
  levels = [];
  rooms = [];
  beds = [];

  constructor(private rest: RestService, private fb: FormBuilder) {
    this.institution = this.rest.getInstitution();

    this.formGroup = this.fb.group({
      building: [{ value: -1, disabled: this.readonly }],
      level: [{ value: -1, disabled: this.readonly }],
      room: [{ value: -1, disabled: this.readonly }],
      bed: [{ value: -1, disabled: this.readonly }],
    });
  }

  buildingChanges(event) {
    // building has changed, reset to default values
    this.levels = [];
    this.rooms = [];
    this.beds = [];

    this.bedData.level = -1;
    this.bedData.room = -1;
    this.bedData.bed  = -1;
    this.bed = {};

    this.bedChanges();

    // get levels if building is valid
    this.rest.get('data/building/' + event.value + '/levels').subscribe(data => {
      this.levels = data['_embedded']['levels'];
      if (this.levels.length === 1) {
        this.bedData.level = this.levels[0]['id'];
        this.formGroup.controls.level.setValue(this.bedData.level);
        this.levelChanges({value: this.bedData.level});
      }
    });
  }

  levelChanges(event) {
    this.rooms = [];
    this.beds = [];

    this.bedData.room = -1;
    this.bedData.bed  = -1;
    this.bed = {};

    this.bedChanges();

    this.rest.get('data/level/' + event.value + '/rooms').subscribe(data => {
      this.rooms = data['_embedded']['rooms'];
      if (this.rooms.length === 1) {
        this.bedData.room = this.rooms[0]['id'];
        this.formGroup.controls.room.setValue(this.bedData.room);
        this.roomChanges({value: this.bedData.room});
      }
    });
  }

  roomChanges(event) {
    this.beds = [];
    this.bedData.bed = -1;
    this.bed = {};

    this.bedChanges();

    this.rest.get('data/room/' + event.value + '/beds').subscribe(data => {
      const beds = data['_embedded']['beds'];
      this.beds = [];
      if (this.unique) {
        beds.forEach(bed => {
          if (bed.personId <= 0) {
            this.beds.push(bed);
          }
        });
      } else {
        this.beds = beds;
      }

      if (this.beds.length === 1) {
        this.bed = this.beds[0];
        this.bedData.bed = this.bed['id'];
        this.formGroup.controls.bed.setValue(this.bedData.bed);
        this.bedChanges();
      }
    });
  }

  bedChanges() {
    this.change.emit(this.bed);
  }

  bedSelected(event) {
    const index = _.findIndex(this.beds, {id: event.value});
    this.bed = this.beds[index];
    this.bedData.bed = event.value;
    this.bedChanges();
  }

  initBedData() {
    if (this.bedId > 0) {
      this.rest.get('data/bed/' + this.bedId).subscribe(data => {
        const ids = data['idString'].split('##');
        this.bedData.building = _.toNumber(ids[0]);
        this.bedData.level = _.toNumber(ids[1]);
        this.bedData.room = _.toNumber(ids[2]);
        this.bedData.bed = this.bedId;

        const observableBatch = [];
        observableBatch.push(this.rest.get('data/institution/' + this.institution.id + '/buildings'));
        observableBatch.push(this.rest.get('data/building/' + this.bedData.building + '/levels'));
        observableBatch.push(this.rest.get('data/level/' + this.bedData.level + '/rooms'));
        observableBatch.push(this.rest.get('data/room/' + this.bedData.room + '/beds'));

        Observable.forkJoin(observableBatch).subscribe(resp => {
          this.buildings = resp[0]['_embedded']['buildings'];
          this.levels = resp[1]['_embedded']['levels'];
          this.rooms = resp[2]['_embedded']['rooms'];

          const beds = resp[3]['_embedded']['beds'];
          this.beds = [];
          if (this.unique) {
            beds.forEach(bed => {
              if (bed.personId <= 0 || bed.id === this.bedId) {
                this.beds.push(bed);
              }
            });
          } else {
            this.beds = beds;
          }

          this.formGroup.controls.building.setValue(this.bedData.building);
          this.formGroup.controls.level.setValue(this.bedData.level);
          this.formGroup.controls.room.setValue(this.bedData.room);
          this.formGroup.controls.bed.setValue(this.bedData.bed);
        }, message => {
          this.rest.showHttpError('deletePersonError', message);
          this.initWithDefault();
        });
      });
    } else {
      this.initWithDefault();
    }
  }

  initWithDefault() {
    this.rest.get('data/institution/' + this.institution.id + '/buildings').subscribe(buildingsData => {
      this.buildings = buildingsData['_embedded']['buildings'];

      if (this.buildings.length === 1 && this.formGroup.controls.building.value === -1) {
        this.bedData.building = this.buildings[0]['id'];
        this.formGroup.controls.building.setValue(this.bedData.building);
        this.buildingChanges({value: this.bedData.building});
      }
    });
  }

  ngOnInit() {
    this.initBedData();
  }
}
